/**
    @author: dt
    @date: 2025-06-23
    @description: 选择器节点
*/

using System.Collections.Generic;
using UnityEngine;

namespace DLib.BehaviorTree
{
    /// <summary>
    /// 选择器节点
    /// 实现OR逻辑，只要有一个子节点成功就返回成功
    /// 按顺序执行子节点，直到遇到成功或运行中的节点
    /// </summary>
    public class Selector : CompositeNode
    {
        /// <summary>是否每次从头开始运行（用于中断机制）</summary>
        private bool alwaysStartFromBeginning;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Selector() : base() 
        {
            alwaysStartFromBeginning = false;
        }
        
        /// <summary>
        /// 带子节点的构造函数
        /// </summary>
        /// <param name="children">子节点列表</param>
        public Selector(List<Node> children) : base(children) 
        {
            alwaysStartFromBeginning = false;
        }

        /// <summary>
        /// 带选项的构造函数
        /// </summary>
        /// <param name="children">子节点列表</param>
        /// <param name="alwaysStartFromBeginning">是否每次从头开始运行</param>
        public Selector(List<Node> children, bool alwaysStartFromBeginning) : base(children)
        {
            this.alwaysStartFromBeginning = alwaysStartFromBeginning;
        }

        /// <summary>
        /// 设置是否每次从头开始运行
        /// </summary>
        /// <param name="value">是否每次从头开始运行</param>
        public void SetAlwaysStartFromBeginning(bool value)
        {
            alwaysStartFromBeginning = value;
        }

        /// <summary>
        /// 评估选择器子节点
        /// 按顺序执行子节点：
        /// - 如果子节点成功，选择器成功
        /// - 如果子节点运行中，选择器运行中
        /// - 如果子节点被中断，选择器被中断
        /// - 如果子节点失败，继续执行下一个子节点
        /// - 如果所有子节点都失败，选择器失败
        /// </summary>
        /// <returns>选择器执行状态</returns>
        protected override NodeState EvaluateChildren()
        {
            // 如果设置为每次从头开始，先尝试前面的节点
            if (alwaysStartFromBeginning)
            {
                // 先尝试执行前面的节点（高优先级）
                for (int i = 0; i < currentChildIndex; i++)
                {
                    Node child = children[i];
                    NodeState childState = child.Evaluate();
                    
                    switch (childState)
                    {
                        case NodeState.Success:
                            // 前面的节点成功，中断当前正在运行的节点
                            InterruptRunningChildren();
                            state = NodeState.Success;
                            return state;
                        case NodeState.Running:
                            // 前面的节点开始运行，中断当前正在运行的节点
                            InterruptRunningChildren();
                            state = NodeState.Running;
                            return state;
                        case NodeState.Interrupted:
                            // 前面的节点被中断
                            state = NodeState.Interrupted;
                            return state;
                        case NodeState.Failure:
                            // 前面的节点失败，继续尝试下一个
                            continue;
                    }
                }
                
                // 如果前面的节点都失败了，继续从当前索引开始
                // 不需要重置currentChildIndex，保持当前执行状态
            }

            // 从当前索引开始遍历所有子节点
            for (int i = currentChildIndex; i < children.Count; i++)
            {
                currentChildIndex = i;
                Node child = children[i];
                NodeState childState = child.Evaluate();

                switch (childState)
                {
                    case NodeState.Success:
                        // 子节点成功，选择器成功
                        state = NodeState.Success;
                        return state;
                    case NodeState.Running:
                        // 子节点运行中，选择器运行中
                        state = NodeState.Running;
                        return state;
                    case NodeState.Interrupted:
                        // 子节点被中断，选择器被中断
                        state = NodeState.Interrupted;
                        return state;
                    case NodeState.Failure:
                        // 子节点失败，继续执行下一个子节点
                        continue;
                }
            }

            // 所有子节点都失败，选择器失败
            state = NodeState.Failure;
            return state;
        }

        /// <summary>
        /// 中断当前正在运行的子节点
        /// </summary>
        private void InterruptRunningChildren()
        {
            for (int i = 0; i < children.Count; i++)
            {
                Node child = children[i];
                if (child.GetState() == NodeState.Running)
                {
                    child.Interrupt();
                }
            }
        }
    }
} 